package com.treeroot.linkedlist;

/**
 * 定义SingleLinkedList,每个SingleLinkedList对象就是一个节点
 * 定义SingleLinkedList 管理heroNode
 */
public class SingleLinkedList {
    //初始化头结点 【不要动】不存放具体的数据，用于索引下面的对象
    private HeroNode head = new HeroNode(0, "", "");

    //添加节点到单向链表 base
    public void add(HeroNode heroNode) {
        //1.当不考虑编号顺序时
        //2.找到当前链表的最后一个节点
        //因为head节点不能动，因此我们需要一个辅助变量 temp
        //temp指向 head节点对象地址，数据共享存入head地址中
        HeroNode temp = head;
        //遍历链表找到最后一个节点
        while (true) {
            if (temp.next == null) {
                break;
            }
            //没有找到就将temp设为最后一个节点
            temp = temp.next;
        }
        //当退出while循环时，temp就指向了链表的最后
        //将最后这个节点的next 指向新的节点
        temp.next = heroNode;
    }

    //添加节点到单向链表 plus
    //第二种方式在添加英雄时，根据排名将英雄插入到指定位置
    // (如果有这个排名，则添加失败，并给出提示）
    public void addPlus(HeroNode heroNode) {
        //因为头结点不能动，通过辅助指针 temp 找到添加的位置
        //因为是单链表，找到是temp的前一个节点，如果没有no字段的话是无法插入的
        HeroNode temp = head;
        //添加编号的标识，no字段是否存在，默认为false
        boolean flag = false;
        while (true) {
            //temp在链表的最后一位
            if (temp.next == null) {
                break;
            }
            //当前的节点编号在要输入的节点编号前，在temp的后面进行插入
            if (temp.next.no > heroNode.no) {
                break;
            }
            //希望添加的节点的编号已经存在
            else if (temp.next.no == heroNode.no) {
                flag = true;
                break;
            }
            //不符合以上条件==>后移temp，继续遍历链表
            temp = temp.next;
        }
        //将最后这个节点的next 指向新的节点
        if (false) {
            System.out.println("准备插入的节点的编号已存在，无法继续加入");
        } else {
            //插入到链表中，temp的后面
            heroNode.next = temp.next;
            temp.next = heroNode;
        }
    }

    //显示链表
    public void list() {
        //判断链表是否为空
        if (head.next == null) {
            System.out.println("链表为空");
        }
        //因为head节点不能动，因此我们需要一个辅助变量 temp
        HeroNode temp = head.next;
        //1.遍历得到数据
        while (true) {
            //判断是否到链表最后了
            if (temp == null) {
                break;
            }
            /**
             * todo:关于输出节点信息 start--------
             * 实际上，temp中的next 保存了每个节点的信息
             * 后移temp只是一种逻辑上的操作，其实并不需要
             * 在打印第一个temp的时候会随之输出下面的next，next就是下面的节点-----
             * 随之递归输出
             * todo:关于输出节点信息 end--------
             */
            //输出节点信息
            System.out.println(temp);
            //将temp后移
            temp = temp.next;
        }

    }

    //修改单节点的信息，根据单节点的no字段修改
    public void update(HeroNode newHeroNode) {
        //1.判断是否为空
        if (head.next == null) {
            System.out.println("链表为空");
        }
        //找到需要修改的节点
        HeroNode temp = head;
        //是否找到了no字段
        boolean flag = false;
        while (true) {
            //已经遍历完成了
            if (temp == null) {
                break;
            }
            //已经找到了
            if (temp.no == newHeroNode.no) {
                flag = true;
                break;
            }
            temp = temp.next;
        }
        //根据flag判断是否找到需要修改的节点
        if (flag) {
            temp.name = newHeroNode.name;
            temp.NickName = newHeroNode.NickName;
        } else {
            System.out.println("【异常数据】没有相应编号的节点");
        }
    }

    //删除某个子节点
    public  void delete(int no) {
        HeroNode temp = head;
        //1.找到被删除的节点的前一个节点
        //表示是否找到找到被删除的节点的前一个节点
        boolean flag = false;
        while (true) {
            //已经到链接的最后了
            if (temp.next == null) {
                break;
            }
            //找到了待删除节点的前一个节点
            if (temp.next.no == no) {
                flag = true;
                break;
            }
            //temp后移继续循环查找
            temp = temp.next;
        }
        if (flag) {
            //进行删除
            temp.next = temp.next.next;
        } else {
            System.out.println("【异常数据】不存在被删除的节点");
        }

    }


}
